'use strict';

const Service = require('egg').Service;
const ulid = require('../public/ulid');
const ConnectOption = require('../oltmodules/ConnectOption');
const ZTEOLT = require('../oltmodules/ZTEOLT');
const HWOLT = require('../oltmodules/HuaWeiOLT');
const XDOLT = require('../oltmodules/XinDeOLT');
const XGLOLT = require('../oltmodules/XinGeLinOLT');
class LineProfileService extends Service {
  async linelist(params) {
    const result = {
      count: '',
      rows: '',
    };
    const where = {}
    where.oltId = params.OltId
    if (params.search) {
      where.name = new RegExp(params.search)
    }
    result.count = await this.ctx.model.LineProfile.find(where).count('_id');
    result.rows = await this.ctx.model.LineProfile.find(where).collation({
      "locale": "zh",
      numericOrdering: true
    }).sort({
      name: 1
    }).skip(parseInt((params.page - 1) * params.limit)).limit(parseInt(params.limit));
    return result;
  }
  async remotelist(params) {
    const result = {
      count: '',
      rows: '',
    };
    const where = {}
    where.oltId = params.OltId
    if (params.search) {
      where.name = new RegExp(params.search)
    }
    result.count = await this.ctx.model.RemoteProfile.find(where).count('_id');
    result.rows = await this.ctx.model.RemoteProfile.find(where).collation({
      "locale": "zh",
      numericOrdering: true
    }).sort({
      name: 1
    }).skip(parseInt((params.page - 1) * params.limit)).limit(parseInt(params.limit));
    return result;
  }
  async lineProfileResult(params){
    const where = {}
    where.oltId = params.OltId
    if (params.id) {
      where._id = params.id
    }
    let result = await this.ctx.model.LineProfile.findOne(where)
    return result;
  }
  async remoteProfileResult(params){
    const where = {}
    where.oltId = params.OltId
    if (params.id) {
      where._id = params.id
    }
    let result = await this.ctx.model.RemoteProfile.findOne(where)
    return result;
  }
  async allList(params) {
    const result = await this.ctx.model.LineProfile.find({
      oltId: params.OltId,
    }).collation({
      "locale": "zh",
      numericOrdering: true
    }).sort({
      name: 1
    });
    return result;
  }

  getBussinessArr(bussinessArr,oltType){
    try {
      let lines = [];
      let remotes = [];
      switch(oltType){
        case "ZTE":
          for(let i = 0;i<bussinessArr.length;i++){
            let bussiness=bussinessArr[i]
            lines.push({
              bName:bussiness.bName,
              dbaProfile:bussiness.dbaProfile,
              DownSpeed:bussiness.DownSpeed,
              isSpeedLimit:bussiness.isSpeedLimit,
              speedType:bussiness.speedType,
              UplinkSpeed:bussiness.UplinkSpeed,
              tcont:i+1,
              gemport:i+1,
            })
            remotes.push({
              bName:bussiness.bName,
              gVLAN : bussiness.gVLAN,
              gemport:i+1,
            })
          }
          break;
        case "HUAWEI":
          lines = bussinessArr
          break;
      }
      return {
        lineBussinessArr:lines,
        remoteBussinessArr:remotes
      }
    } catch (error) {
      console.log(error);
      return {
        lineBussinessArr:null,
        remoteBussinessArr:null
      }
    }
    
  }
  async create(params) {
    const result = {
      msg: '',
      flag: false,
    };
    try {
      console.log('接受的参数', params);
      const oltResult = await this.ctx.model.Olt.findOne({
        _id: params.oltId
      });
      const lineProfileResult = await this.ctx.model.LineProfile.findOne({
        name: params.name,
        oltId: params.oltId
      });
      if (lineProfileResult) {
        result.msg = "create lineprofile fail,this name is exist"
        result.flag = false
        return result
      }
      await lineProfileCreate(oltResult, params, this);
      let {lineBussinessArr,remoteBussinessArr} = this.getBussinessArr(params.bussinessArr,oltResult.oltType);
      if(lineBussinessArr&&lineBussinessArr.length>0){
        await this.ctx.model.LineProfile.create({
          _id: ulid.ulid(),
          name: params.name,
          description: params.description,
          oltId: params.oltId,
          bussinessArr: lineBussinessArr,
          isJEDICreate: true
        });
      }
      if(remoteBussinessArr&&remoteBussinessArr.length>0){
        await this.ctx.model.RemoteProfile.create({
          _id: ulid.ulid(),
          name: params.name,
          description: params.description,
          oltId: params.oltId,
          bussinessArr: remoteBussinessArr,
          isJEDICreate: true
        })
      }
      result.msg = 'create lineprofile successful';
      result.flag = true;
      return result;
    } catch (error) {
      result.msg = 'create lineprofile fail,' + error;
      result.flag = false;
      return result;
    }
  }
  async delete(params) {
    const result = {
      msg: '',
      flag: false,
    };
    try {
      const lineProfileResult = await this.ctx.model.LineProfile.findOne({
        _id: params.id
      });
      const oltResult = await this.ctx.model.Olt.findOne({
        _id: lineProfileResult.oltId
      });
      await lineProfileDelete(lineProfileResult, oltResult, this);
      await this.ctx.model.LineProfile.deleteOne({
        _id: params.id
      });
      result.msg = 'delete lineprofile successful';
      result.flag = true;
      return result;
    } catch (error) {
      result.msg = 'delete lineprofile fail,' + error,
        result.flag = false;
      return result;
    }
  }
  async edit(params) {
    const result = {
      msg: '',
      flag: false,
    };
    try {
      await this.ctx.model.LineProfile.updateOne({
        _id: params.id
      }, {
        $set: {
          description: params.description
        }
      });
      result.msg = 'edit lineprofile successful';
      result.flag = true;
      return result;
    } catch (error) {
      result.msg = 'edit lineprofile fail,' + error,
        result.flag = false;
      return result;
    }
  }
  async checkLineProfileName(name, OltId) {
    try {
      const oltInformation = await this.ctx.model.Olt.findOne({
        _id: OltId
      });
      const options = new ConnectOption(oltInformation.oltIP, oltInformation.initCommunity, oltInformation.snmpUDPPort, 162, true, true, oltInformation.telnetTCPPort, oltInformation.oltManagementPassword, oltInformation.oltTelnetUsername, oltInformation.oltTelnetPassword, oltInformation.systemName, oltInformation.RZUsername, oltInformation.RZPassword,oltInformation.telnetProxySwitch);
      let result;
      let me = this;
      switch (oltInformation.oltType) {
        case 'ZTE': {
          // zte 没有 lineprofile
          const zte = new ZTEOLT(options);
          result = await zte.lineProfileNameCheck(oltInformation.oltHardVersion, name, me);
          if (result instanceof Array) {
            let repeatItem = result.find(item => {
              return item === name.trim()
            })
            if (repeatItem) {
              return true;
            } else {
              return false;
            }
          }
          break;
        }
        case 'HUAWEI': {
          const hw = new HWOLT(options);
          result = await hw.lineProfileNameCheck(name, me);
          if (result instanceof Array) {
            let repeatItem = result.find(item => {
              console.log(item.profileName);
              return item.profileName && item.profileName.trim() === name.trim()
            })
            if (repeatItem) {
              return true;
            } else {
              return false;
            }
          }
          break;
        }
        default:
          break;
      }
      return result;
    } catch (error) {
      throw error;
    }
  }
}

async function lineProfileCreate(oltInformation, params, me) {
  try {
    const options = new ConnectOption(oltInformation.oltIP, oltInformation.initCommunity, oltInformation.snmpUDPPort, 162, true, true, oltInformation.telnetTCPPort, oltInformation.oltManagementPassword, oltInformation.oltTelnetUsername, oltInformation.oltTelnetPassword, oltInformation.systemName, oltInformation.RZUsername, oltInformation.RZPassword,oltInformation.telnetProxySwitch);
    let result;
    switch (oltInformation.oltType) {
      case 'ZTE': {
        // zte 没有 lineprofile
        const zte = new ZTEOLT(options);
        const {
          name,
          bussinessArr
        } = params;
        result = await zte.lineProfileCreate(oltInformation.oltHardVersion, name, bussinessArr, me);
        break;
      }
      case 'HUAWEI': {
        const hw = new HWOLT(options);
        const {
          name,
          bussinessArr
        } = params;
        result = await hw.lineProfileCreate(name, bussinessArr, me);
        break;
      }
      default:
        break;
    }
    return result;
  } catch (error) {
    throw error;
  }
}

async function lineProfileDelete(lineProfileResult, oltInformation, me) {
  try {
    const options = new ConnectOption(oltInformation.oltIP, oltInformation.initCommunity, oltInformation.snmpUDPPort, 162, true, true, oltInformation.telnetTCPPort, oltInformation.oltManagementPassword, oltInformation.oltTelnetUsername, oltInformation.oltTelnetPassword, oltInformation.systemName, oltInformation.RZUsername, oltInformation.RZPassword,oltInformation.telnetProxySwitch);
    let result;
    switch (oltInformation.oltType) {
      case 'ZTE': {
        // zte 没有 lineprofile
        const zte = new ZTEOLT(options);
        result = await zte.lineProfileDelete(oltInformation.oltHardVersion, lineProfileResult.name, me);
        break;
      }
      case 'HUAWEI': {
        const hw = new HWOLT(options);
        result = await hw.lineProfileDelete(lineProfileResult.name, me);
        break;
      }
      default:
        break;
    }
    return result;
  } catch (error) {
    throw error;
  }
}

async function getIndex(speedProfileAll) {
  const arr = [];
  for (var i = 0; i < 8193; i++) {
    arr.push(i);
  }
  const speedIndexArr = [];
  for (var i = 0; i < speedProfileAll.length; i++) {
    speedIndexArr.push(parseInt(speedProfileAll[i].index));
  }
  const result = await getSubArray(arr, speedIndexArr);
  return result[0];
}
async function getSubArray(arr1, arr2) {
  const set1 = new Set(arr1);
  const set2 = new Set(arr2);
  const result = [];
  set1.forEach((item, index) => {
    if (!set2.has(item)) {
      result.push(item);
    }
  });
  return result;
}


module.exports = LineProfileService;